﻿using System;
using System.Globalization; // KoreanLunisolarCalendar가 있는 컴포넌트

namespace dodone
{
    /// <summary>양력 날짜를 음력 날짜로 변환합니다.</summary>
    class SolarToLunaDate
    {
        private KoreanLunisolarCalendar lDate = new KoreanLunisolarCalendar();
        private int lYear; // luna year
        private int lMonth; // luna month
        private int lDay; // luna day
        private DateTime sDate; // solar date
        private bool lLeapMonth = false; // leap month[윤달]

        /// <summary>오늘 양력 날짜로 음력 날짜를 초기화합니다.</summary>
        public SolarToLunaDate() // default constructor, today
        {
            sDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);

            checkLeap();
        }

		/// <summary>지정한 양력 날짜로 음력 날짜를 나타냅니다.</summary>
		/// <param name="year">양력 날짜</param>
		public SolarToLunaDate(DateTime date) // overload constructor, solar to luna
		{
			sDate = new DateTime(date.Year, date.Month, date.Day);

			checkLeap();
		}

        /// <summary>지정한 양력 날짜로 음력 날짜를 나타냅니다.</summary>
        /// <param name="year">양력 연도</param>
        /// <param name="month">양력 월</param>
        /// <param name="day">양력 일</param>
        public SolarToLunaDate(int year, int month, int day) // overload constructor, solar to luna
        {
            sDate = new DateTime(year, month, day);

            checkLeap();
        }

        private void checkLeap()
        {
            lYear = lDate.GetYear(sDate);
            lMonth = lDate.GetMonth(sDate);
            lDay = lDate.GetDayOfMonth(sDate);

            if (lDate.GetMonthsInYear(lYear) > 12) // exist leap month
            {
                if (lMonth == lDate.GetLeapMonth(lYear))
                {
                    lLeapMonth = true;
                    lMonth--;
                }
                else if (lMonth > lDate.GetLeapMonth(lYear))
                    lMonth--;
            }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 연도 구성 요소를 가져옵니다.</summary>
        public int LunaYear
        {
            get { return lYear; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 월 구성 요소를 가져옵니다.</summary>
        public int LunaMonth
        {
            get { return lMonth; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 일 구성 요소를 가져옵니다.</summary>
        public int LunaDay
        {
            get { return lDay; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜가 윤달인지 여부를 확인합니다.</summary>
        public bool IsLeapMonth
        {
			get { return lLeapMonth; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜가 윤달이 있는지 여부를 확인합니다.</summary>
        public bool IsExistLeapMonth
        {
			get
			{
				if (lDate.GetMonthsInYear(lYear) > 12)
					return true;
				else
					return false;
			}
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 연도 구성 요소를 가져옵니다.</summary>
        public int SolarYear
        {
            get { return sDate.Year; }
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 월 구성 요소를 가져옵니다.</summary>
        public int SolarMonth
        {
            get { return sDate.Month; }
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 일 구성 요소를 가져옵니다.</summary>
        public int SolarDay
        {
			get { return sDate.Day; }
        }
    }

    /// <summary>음력 날짜를 양력 날짜로 변환합니다.</summary>
    class LunaToSolarDate
    {
        private KoreanLunisolarCalendar lDate = new KoreanLunisolarCalendar();
        private int lYear; // luna year
        private int lMonth; // luna month
        private int lDay; // luna day
        private DateTime sDate; // solar date
        private bool lLeapMonth; // leap month[윤달]

        /// <summary>지정한 음력 날짜로 양력 날짜를 나타냅니다.</summary>
        /// <param name="year">음력 연도</param>
        /// <param name="month">음력 월</param>
        /// <param name="day">음력 일</param>
        /// <param name="day">윤달일 경우 True, 평달일 경우 False</param>
        public LunaToSolarDate(int year, int month, int day, bool leapmonth)
        {
            lYear = year;
            lMonth = month;
            lDay = day;

            if (IsExistLeapMonth)
                lLeapMonth = leapmonth;
            else // not exist leap month
                lLeapMonth = false; // set to common month

            if (lLeapMonth)
                sDate = lDate.ToDateTime(lYear, lMonth + 1, lDay, 0, 0, 0, 0);
            else
                sDate = lDate.ToDateTime(lYear, lMonth, lDay, 0, 0, 0, 0);
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 연도 구성 요소를 가져옵니다.</summary>
        public int LunaYear
        {
            get { return lYear; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 월 구성 요소를 가져옵니다.</summary>
        public int LunaMonth
        {
            get { return lMonth; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜의 일 구성 요소를 가져옵니다.</summary>
        public int LunaDay
        {
            get { return lDay; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜가 윤달인지 여부를 확인합니다.</summary>
        public bool IsLeapMonth
        {
            get { return lLeapMonth; }
        }

        /// <summary>이 인스턴스가 나타내는 음력 날짜가 윤달이 있는지 여부를 확인합니다.</summary>
        public bool IsExistLeapMonth
        {
			get
			{
				if (lDate.GetMonthsInYear(lYear) > 12)
					return true;
				else
					return false;
			}
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 연도 구성 요소를 가져옵니다.</summary>
        public int SolarYear
        {
            get { return sDate.Year; }
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 월 구성 요소를 가져옵니다.</summary>
        public int SolarMonth
        {
            get { return sDate.Month; }
        }

        /// <summary>이 인스턴스가 나타내는 양력 날짜의 일 구성 요소를 가져옵니다.</summary>
        public int SolarDay
        {
			get { return sDate.Day; }
        }
    }
}
